package com.gnerv.cms.util;

import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author Gnerv LiGen
 * @description 日志工具类
 * @data 2019/5/31
 */
public class LogUtil {

    private static Logger logger = LoggerFactory.getLogger(LogUtil.class);

    public static void info(String msg, Object... tag) {
        StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[2];
        LogInfo logInfo = getLogInfo(stackTraceElement);
        logger.info(msg, tag);
        logger.info(logInfo.toString());
    }

    public static void warn(String msg, Object... tag) {
        StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[2];
        LogInfo logInfo = getLogInfo(stackTraceElement);
        logger.warn(msg, tag);
        logger.warn(logInfo.toString());
    }

    public static void error(String msg, Object... tag) {
        StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[2];
        LogInfo logInfo = getLogInfo(stackTraceElement);
        logger.error(msg, tag);
        logger.error(logInfo.toString());
    }

    public static void debug(String msg, Object... tag) {
        StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[2];
        LogInfo logInfo = getLogInfo(stackTraceElement);
        logger.debug(msg, tag);
        logger.debug(logInfo.toString());
    }

    public static void trace(String msg, Object... tag) {
        StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[2];
        LogInfo logInfo = getLogInfo(stackTraceElement);
        logger.trace(msg, tag);
        logger.trace(logInfo.toString());
    }

    /**
     * 输出日志所在类和方法的信息
     *
     * @param stackTraceElement 执行线程
     */
    private static LogInfo getLogInfo(StackTraceElement stackTraceElement) {
        // 获取线程名
        String threadName = Thread.currentThread().getName();
        // 获取线程ID
        long threadId = Thread.currentThread().getId();
        // 获取文件名.即xxx.java
        String fileName = stackTraceElement.getFileName();
        // 获取类名.即包名+类名
        String className = stackTraceElement.getClassName();
        // 获取方法名称
        String methodName = stackTraceElement.getMethodName();
        // 获取行号
        int lineNumber = stackTraceElement.getLineNumber();
        LogInfo logInfo = new LogInfo();
        logInfo.setThreadName(threadName);
        logInfo.setThreadId(threadId);
        logInfo.setClassName(className);
        logInfo.setMethodName(methodName);
        logInfo.setLineNumber(lineNumber);
        return logInfo;
    }

    private static class LogInfo {

        /**
         * 线程名称
         */
        String threadName;
        /**
         * 线程id
         */
        long threadId;
        /**
         * 全类名
         */
        String className;
        /**
         * 方法名
         */
        String methodName;
        /**
         * 方法所在行
         */
        int lineNumber;

        public String getThreadName() {
            return threadName;
        }

        public void setThreadName(String threadName) {
            this.threadName = threadName;
        }

        public long getThreadId() {
            return threadId;
        }

        public void setThreadId(long threadId) {
            this.threadId = threadId;
        }

        public String getClassName() {
            return className;
        }

        public void setClassName(String className) {
            this.className = className;
        }

        public String getMethodName() {
            return methodName;
        }

        public void setMethodName(String methodName) {
            this.methodName = methodName;
        }

        public int getLineNumber() {
            return lineNumber;
        }

        public void setLineNumber(int lineNumber) {
            this.lineNumber = lineNumber;
        }

        @Override
        public String toString() {
            return JSON.toJSONString(this);
        }
    }

}